package org.finesys.codegen.service.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.finesys.codegen.constants.DefaultConstants;
import org.finesys.codegen.entity.GenGroup;
import org.finesys.codegen.entity.GenTemplate;
import org.finesys.codegen.entity.GenTemplateGroup;
import org.finesys.codegen.mapper.GenGroupMapper;
import org.finesys.codegen.mapper.GenTemplateGroupMapper;
import org.finesys.codegen.mapper.GenTemplateMapper;
import org.finesys.codegen.properties.CodeGenDefaultProperties;
import org.finesys.codegen.service.GenTemplateService;
import org.finesys.codegen.vo.GenTemplateFileVO;
import org.finesys.common.core.exception.CheckedException;
import org.finesys.common.core.module.R;
import org.finesys.common.mp.core.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@RequiredArgsConstructor
@Slf4j
public class GenTemplateServiceImpl extends BaseServiceImpl<GenTemplateMapper, GenTemplate> implements GenTemplateService {


    private final GenGroupMapper genGroupMapper;
    private final GenTemplateGroupMapper genTemplateGroupMapper;
    private final CodeGenDefaultProperties codeGenDefaultProperties;

    @Override
    public R<?> checkVersion() {
        //关闭在线更新
        if (!codeGenDefaultProperties.isAutoCheckVersion()) {
            return R.success(true);
        }
        //读取配置文件
        Map<String, Object> configAndVersion = getConfigAndVersion();
        JSONObject configJsonObj = (JSONObject) configAndVersion.get("configJSON");
        String versionFile = (String) configAndVersion.get("versionFile");
        //获取全部模板信息
        Set<String> cgtmConfigGroupNames = configJsonObj.keySet();
        String cgtmConfigGroupName = cgtmConfigGroupNames.iterator().next();
        //是否存在
        boolean exists = genGroupMapper.exists(Wrappers.<GenGroup>lambdaQuery().eq(GenGroup::getGroupName, cgtmConfigGroupName + versionFile));
        return R.success(exists);
    }

    /**
     * 在线更新
     */

    @Override
    public R<?> onlineUpdate() {
        //关闭在线更新
        if (!codeGenDefaultProperties.isAutoCheckVersion()) {
            return R.success(true);
        }
        //读取配置文件
        Map<String, Object> configAndVersion = getConfigAndVersion();
        JSONObject configJsonObj = (JSONObject) configAndVersion.get("configJSON");
        String versionFile = (String) configAndVersion.get("versionFile");
        //获取全部模板信息
        Set<String> cgtmConfigGroupNames = configJsonObj.keySet();
        String cgtmConfigGroupName = cgtmConfigGroupNames.iterator().next();
        //是否存在
        boolean exists = genGroupMapper.exists(Wrappers.<GenGroup>lambdaQuery().eq(GenGroup::getGroupName, cgtmConfigGroupName + versionFile));
        if (exists) {
            return R.failed("已是最新版本，无需更新");
        }
        insertTemplateFiles(versionFile, configJsonObj, cgtmConfigGroupNames);
        return R.success("更新版本成功，版本号：" + versionFile);
    }

    /***
     * 更新模板信息
     * */
    private void insertTemplateFiles(String versionFile, JSONObject configJsonObj, Set<String> cgtmConfigGroupNames) {
        Iterator<String> iterator = cgtmConfigGroupNames.iterator();
        while (iterator.hasNext()) {
            //组名称
            String cgtmConfigGroupName = iterator.next();
            //创建新的group
            GenGroup genGroup = new GenGroup();
            genGroup.setGroupName(cgtmConfigGroupName + versionFile);
            genGroup.setGroupDesc(cgtmConfigGroupName);
            genGroupMapper.insert(genGroup);
            //解析json配置文件
            List<GenTemplateFileVO> templateFileVOList = configJsonObj.getBeanList(cgtmConfigGroupName, GenTemplateFileVO.class);
            for (GenTemplateFileVO templateFileVO : templateFileVOList) {
                //1、读取文件
                String templateFile = getCGTMFile(templateFileVO.getTemplateFile());
                //2、保存模板文件信息到数据库
                GenTemplate genTemplate = new GenTemplate();
                genTemplate.setTemplateName(templateFileVO.getTemplateName());
                genTemplate.setGeneratorPath(templateFileVO.getGeneratorPath());
                genTemplate.setTemplateDesc(cgtmConfigGroupName + templateFileVO.getTemplateDesc());
                genTemplate.setTemplateCode(templateFile);
                baseMapper.insert(genTemplate);
                //3、保存
                GenTemplateGroup genTemplateGroup = new GenTemplateGroup();
                genTemplateGroup.setGroupId(genGroup.getGroupId());
                genTemplateGroup.setTemplateId(genTemplate.getTemplateId());
                genTemplateGroupMapper.insert(genTemplateGroup);
            }
        }
    }

    /**
     * 获取配置文件和版本信息
     */
    private Map<String, Object> getConfigAndVersion() {
        Map<String, Object> config = new HashMap<>(16);
        String configFile = getCGTMFile("config.json");
        String versionFile = getCGTMFile("VERSION");
        //解析config.json
        JSONObject jsonObject = JSONUtil.parseObj(configFile);
        config.put("configJSON", jsonObject);
        config.put("versionFile", versionFile);
        return config;
    }

    /**
     * 获取cgtm文件
     */
    private String getCGTMFile(String fileName) {
        HttpResponse response = HttpRequest.get(String.format("%s/CGTM/raw/master/%s", DefaultConstants.CGTM_URL, fileName)).execute();
        if (response.getStatus() == HttpStatus.HTTP_OK || StringUtils.hasText(response.body())) {
            return response.body();
        }
        if (log.isWarnEnabled()) {
            log.warn("获取文件失败:{},Http Code:{}", fileName, response.getStatus());
        }
        throw new CheckedException("获取文件失败");
    }
}
